package shining365.programmableweb.data.common;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationFactory;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;

public class Utils {

	private static Configuration configuration = null;

	static {
		try {
			ConfigurationFactory factory = new ConfigurationFactory();
			factory.setConfigurationURL(
					ConfigurationFactory.class.getResource("/configurationSources.xml"));
			configuration = factory.getConfiguration();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	public static Configuration getConfiguration() {
		return configuration;
	}

	public static byte[] readFile(String filePath) throws IOException {
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		FileInputStream is = new FileInputStream(filePath);
		try {
			IOUtils.copy(is, os);
			return os.toByteArray();
		} finally {
			is.close();
		}
	}

	public static void writeFile(byte[] data, String filePath) throws IOException {
		FileOutputStream is = new FileOutputStream(filePath);
		try {
			is.write(data);
		} finally {
			is.close();
		}
	}
	
	@SuppressWarnings("unchecked")
	public static <T> T unmarshall(Class<T> clazz, String xml)
			throws JAXBException, IOException {
		JAXBContext jc = JAXBContext
			.newInstance(clazz.getPackage().getName());
		Unmarshaller unmarshaller = jc.createUnmarshaller();
		ByteArrayInputStream xmlStream = new ByteArrayInputStream(xml.getBytes());
		T jaxbObject = (T)unmarshaller.unmarshal(xmlStream);
		return jaxbObject;
	}
	
	public static <T> String marshall(T jaxbObject) throws JAXBException {
		JAXBContext jc = JAXBContext
				.newInstance(jaxbObject.getClass().getPackage().getName());
		Marshaller marshaller = jc.createMarshaller();
		marshaller.setProperty("jaxb.formatted.output", true);
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		marshaller.marshal(jaxbObject, out);
		return new String(out.toByteArray());
	}
	
	public static <T> T unmarshallFromFile(Class<T> clazz, String filePath)
			throws JAXBException, IOException {
		return unmarshall(clazz, new String(readFile(filePath)));
	}

	public static <T> void marshallToFile(T jaxbObject, String filePath)
			throws JAXBException, IOException {
		writeFile(marshall(jaxbObject).getBytes(), filePath);
	}
	
	@SuppressWarnings("unused")
	private static final Logger logger = Logger.getLogger(Utils.class);
}
